package com.vi.hcnetsdk.simpleapp;

import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.content.Context;
import android.view.SurfaceView;
import android.view.View;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;

import com.vi.hcnetsdk.jna.HCNetSDKByJNA.NET_DVR_ALARMER;
import com.vi.hcnetsdk.jna.HCNetSDKByJNA;
import com.vi.hcnetsdk.jna.HCNetSDKJNAInstance;
import com.hikvision.netsdk.ExceptionCallBack;
import com.hikvision.netsdk.HCNetSDK;
import com.hikvision.netsdk.INT_PTR;
import com.hikvision.netsdk.NET_DVR_PREVIEWINFO;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;

/**
 * Created by xulin9 on 2017/9/8.
 * no try catch module, fix it get more good performance
 */

class DeviceManage {
    public final static String DEMOTAG = "SimpleDemo";
    private static final String SD_CARD_LOG_PATH = Environment.getExternalStorageDirectory().getAbsolutePath() + "/SmpleDemo/sdklog/";
    private static DeviceManage mDeviceManage = null;
    private static Handler mHandler;
    private static Handler mVoiceTalkHandler;
    public static final int ADD_TO_LIST = 0x1000;
    public static final int VIDEO_CALL_PROCESS = 0x2000;

    //device related information
    private int mStartChan = 0;
    public int mChanNum = 0;
    private int mPlaybackID = -1;
    public int mUserID = -1;
    private int mAlarmID = -1;
    private int mVoiceTalkHandle = -1;
    private int mVideoCall = -1;

    private static boolean bInited = false;

    private DataModal.CallParams mCallParams;

    private DeviceManage() {
        // Exists only to defeat instantiation.
    }

    public void setHandler(Handler handler, Handler vtHandler) {
        mHandler = handler;
        mVoiceTalkHandler = vtHandler;
    }

    @Override
    protected void finalize() {
        Log.i(DEMOTAG, "NET_DVR_Cleanup");
        if (mUserID >= 0) {
            if (mAlarmID >= 0) {
                stopAlarm();
            }
            logout();
        }
        bInited = false;
        HCNetSDK.getInstance().NET_DVR_Cleanup();
    }

    public boolean init(Context context) {
        //mContext = context;
        if (!bInited) {
            bInited = true;
            return initSdk();
        }

        //关闭连接
        if (mUserID >= 0) {
            if (mAlarmID >= 0) {
                stopAlarm();
            }
            logout();
        }
        return true;
    }

    public static DeviceManage getInstance() {
        if (mDeviceManage == null) {
            synchronized (DeviceManage.class) {
                if (null == mDeviceManage) {
                    mDeviceManage = new DeviceManage();
                }
            }
        }
        return mDeviceManage;
    }


    //获取错误码
    public int GetLastError() {
        return HCNetSDKJNAInstance.getInstance().NET_DVR_GetLastError();
    }

    /**
     * @return success-true,failed-false
     */
    private boolean initSdk() {
        // init net sdk
        if (!HCNetSDK.getInstance().NET_DVR_Init()) {
            Log.e(DEMOTAG, "HCNetSDK init is failed!");
            return false;
        }
        //HCNetSDK.getInstance().NET_DVR_Init();
        //设置日志路径
//        HCNetSDK.getInstance().NET_DVR_SetLogToFile(3, SD_CARD_LOG_PATH, true);

        HCNetSDK.getInstance().NET_DVR_SetLogToFile(3, "/mnt/sdcard/sdklog/", true);

        return true;
    }


    /**
     * @param ip
     * @param port
     * @param userName
     * @param password
     * @return
     */
    public int loginNormalDevice(String ip, int port, String userName, String password) {
        HCNetSDKByJNA.NET_DVR_USER_LOGIN_INFO loginInfo = new HCNetSDKByJNA.NET_DVR_USER_LOGIN_INFO();
        System.arraycopy(ip.getBytes(), 0, loginInfo.sDeviceAddress, 0, ip.length());
        System.arraycopy(userName.getBytes(), 0, loginInfo.sUserName, 0, userName.length());
        System.arraycopy(password.getBytes(), 0, loginInfo.sPassword, 0, password.length());
        loginInfo.wPort = (short) port;
        HCNetSDKByJNA.NET_DVR_DEVICEINFO_V40 deviceInfo = new HCNetSDKByJNA.NET_DVR_DEVICEINFO_V40();
        loginInfo.write();
        // call NET_DVR_Login_V40 to login on
        int lUserID = HCNetSDKJNAInstance.getInstance().NET_DVR_Login_V40(loginInfo.getPointer(), deviceInfo.getPointer());

        if (lUserID < 0) {
            Log.e(DEMOTAG, "NET_DVR_Login_V40 failed with:" + HCNetSDKJNAInstance.getInstance().NET_DVR_GetLastError());
            return -1;
        } else {
            MainActivity.m_UserId = lUserID;
            deviceInfo.read();
            //Log.i(DEMOTAG, "NET_DVR_Login_V40 succ with:" + lUserID);
        }

        if (deviceInfo.struDeviceV30.byChanNum > 0) {
            mStartChan = deviceInfo.struDeviceV30.byStartChan;
            mChanNum = deviceInfo.struDeviceV30.byChanNum;
        } else if (deviceInfo.struDeviceV30.byIPChanNum > 0) {
            mStartChan = deviceInfo.struDeviceV30.byStartDChan;
            mChanNum = deviceInfo.struDeviceV30.byIPChanNum + deviceInfo.struDeviceV30.byHighDChanNum * 256;
        }
        MainActivity.m_StartChan = mStartChan;
        if (mChanNum == 1) {
            MainActivity.m_DeviceType = 1;
        } else {
            MainActivity.m_DeviceType = 0;
        }
        Log.i(DEMOTAG, "NET_DVR_LoginV40 is Successful!");

        mUserID = lUserID;
        return lUserID;
    }

    public void logout() {
        if (mUserID >= 0) {
            if (!HCNetSDKJNAInstance.getInstance().NET_DVR_Logout(mUserID)) {
                System.out.println("NET_DVR_Logout failed with:" + HCNetSDKJNAInstance.getInstance().NET_DVR_GetLastError());
            } else {
                mUserID = -1;
                System.out.println("NET_DVR_Logout succ");
            }
        }
        return;
    }

    public boolean startSinglePreview(SurfaceView playView) {
        if (mPlaybackID >= 0) {
            Log.i(DEMOTAG, "Please stop palyback first");
            return false;
        }
        Log.i(DEMOTAG, "m_iStartChan:" + mStartChan);

        NET_DVR_PREVIEWINFO previewInfo = new NET_DVR_PREVIEWINFO();
        previewInfo.lChannel = mStartChan;
        previewInfo.dwStreamType = 0; // substream
        previewInfo.bBlocked = 1;
        previewInfo.hHwnd = playView.getHolder();
//        previewInfo.hHwnd = null;
        // HCNetSDK start preview
        Log.i(DEMOTAG, "mUserID:" + mUserID);
        mPlaybackID = HCNetSDK.getInstance().NET_DVR_RealPlay_V40(mUserID, previewInfo, null);
        if (mPlaybackID < 0) {
            Log.e(DEMOTAG, "NET_DVR_RealPlay is failed!Err:" + HCNetSDK.getInstance().NET_DVR_GetLastError());
            return false;
        }
        Log.e("DEMOTAG", "NET_DVR_RealPlay is failed!Err:" + HCNetSDK.getInstance().NET_DVR_GetLastError());
//        boolean bRet = HCNetSDKJNAInstance.getInstance().NET_DVR_OpenSound(mUserID);

        Log.i(DEMOTAG, "NetSdk Play sucess");
        return true;
    }


    public void stopSinglePreview() {
        if (mPlaybackID < 0) {
            Log.i(DEMOTAG, "m_iPlayID < 0");
            return;
        }

        // net sdk stop preview
        if (!HCNetSDK.getInstance().NET_DVR_StopRealPlay(mPlaybackID)) {
            Log.e(DEMOTAG, "StopRealPlay is failed!Err:" + HCNetSDK.getInstance().NET_DVR_GetLastError());
            return;
        }

        mPlaybackID = -1;
    }

    public static class fVideoCallCallback implements HCNetSDKByJNA.fRemoteConfigCallback {
        @Override
        public void invoke(int dwType, Pointer lpBuffer, int dwBufLen, Pointer pUserData) {
            Log.i(DEMOTAG, "process video call command");
            if (dwType == HCNetSDKByJNA.NET_SDK_CALLBACK_TYPE_STATUS) {
                int dwStates = lpBuffer.getInt(0);
                if (dwStates != HCNetSDKByJNA.NET_SDK_CALLBACK_STATUS_PROCESSING) {
                    if (mVoiceTalkHandler != null) {
                        Message msg = new Message();
                        msg.obj = dwStates;
                        msg.what = VIDEO_CALL_PROCESS;
                        mVoiceTalkHandler.sendMessage(msg);
                    }
                }
            } else if (dwType == HCNetSDKByJNA.NET_SDK_CALLBACK_TYPE_DATA) {
                HCNetSDKByJNA.NET_DVR_VIDEO_CALL_PARAM struVideoCallParam = new HCNetSDKByJNA.NET_DVR_VIDEO_CALL_PARAM(lpBuffer);
                struVideoCallParam.read();

                DataModal.CallParams oneItem = new DataModal.CallParams();
                oneItem.deviceType = struVideoCallParam.byUnitType;
                oneItem.buildingNumber = struVideoCallParam.wBuildingNumber;
                oneItem.deviceIndex = struVideoCallParam.wDevIndex;
                oneItem.roomNumber = struVideoCallParam.wRoomNumber;
                oneItem.foorNumber = struVideoCallParam.wFloorNumber;
                oneItem.commandType = VI_CTRL_COMMAND.values()[struVideoCallParam.dwCmdType];
                oneItem.period = struVideoCallParam.wPeriod;
                oneItem.unitNumber = struVideoCallParam.wUnitNumber;

                if (mVoiceTalkHandler != null) {
                    Message msg = new Message();
                    msg.obj = oneItem;
                    msg.what = VIDEO_CALL_PROCESS;
                    mVoiceTalkHandler.sendMessage(msg);
                }
            }
        }
    }

    //返回值： 0-成功，其他失败
    public int operate_lock(DataModal.ControlLockData data) {
        //远程开锁控制
        HCNetSDKByJNA.NET_DVR_CONTROL_GATEWAY struGateWay = new HCNetSDKByJNA.NET_DVR_CONTROL_GATEWAY();
        struGateWay.dwSize = struGateWay.size();
        struGateWay.dwGatewayIndex = data.gateway_index;
        struGateWay.byCommand = (byte) data.command;
        struGateWay.byLockType = (byte) data.lock_type;
        struGateWay.wLockID = (short) data.lock_id;
        struGateWay.byControlType = (byte) data.control_type;
        if (data.control_src != null) struGateWay.byControlSrc = data.control_src.getBytes();
        if (data.passwd != null) struGateWay.byPassword = data.passwd.getBytes();
        struGateWay.write();
        Log.i(DEMOTAG, "struGateWay:" + struGateWay.dwGatewayIndex + " " + struGateWay.byCommand + " " + struGateWay.byLockType + " " + struGateWay.wLockID + " " + struGateWay.byControlType + " " + data.control_src + " " + data.passwd);
        boolean iRet = HCNetSDKJNAInstance.getInstance().NET_DVR_RemoteControl(mUserID, HCNetSDKByJNA.NET_DVR_REMOTECONTROL_GATEWAY, struGateWay.getPointer(), struGateWay.size());
        if (!iRet) {
            Log.i(DEMOTAG, "NET_DVR_REMOTECONTROL_GATEWAY failed:" + HCNetSDKJNAInstance.getInstance().NET_DVR_GetLastError());
            return HCNetSDKJNAInstance.getInstance().NET_DVR_GetLastError();
        }
        return 0;
    }

    public enum VI_CTRL_COMMAND {
        REQUEST_CALL(0), CANCLE_CALL(1), ANSWER_CALL(2), REJECT_CALL(3), NO_ANSWER_TIMEOUT(4), HANG_UP(5), DEVICE_BUSY(6), CLIENT_BUSY(7), INDOOR_UNIT_OFFLINE(8);

        private int nCode;

        private VI_CTRL_COMMAND(int _nCode) {
            this.nCode = _nCode;
        }

        public int toInt() {
            return this.nCode;
        }

        @Override
        public String toString() {
            return String.valueOf(this.nCode);
        }
    }

    public void setCallParams(DataModal.CallParams callParams) {
        mCallParams = callParams;
    }

    public boolean sendSessionCtrlCmd(VI_CTRL_COMMAND cmd) {
        if (mCallParams == null) return false;

        HCNetSDKByJNA.NET_DVR_VIDEO_CALL_PARAM struVideoCallParam = new HCNetSDKByJNA.NET_DVR_VIDEO_CALL_PARAM();
        struVideoCallParam.dwSize = struVideoCallParam.size();
        struVideoCallParam.dwCmdType = cmd.toInt();
        struVideoCallParam.wPeriod = mCallParams.period;
        struVideoCallParam.wBuildingNumber = mCallParams.buildingNumber;
        struVideoCallParam.wDevIndex = mCallParams.deviceIndex;
        struVideoCallParam.wFloorNumber = mCallParams.foorNumber;
        struVideoCallParam.wRoomNumber = mCallParams.roomNumber;
        struVideoCallParam.wUnitNumber = mCallParams.unitNumber;
        struVideoCallParam.byUnitType = (byte) mCallParams.deviceType;
        struVideoCallParam.write();
        if (!HCNetSDKJNAInstance.getInstance().NET_DVR_SendRemoteConfig(mVideoCall, 0, struVideoCallParam.getPointer(), struVideoCallParam.size())) {
            Log.i(DEMOTAG, "NET_DVR_SendRemoteConfig fail, dwCmdType:" + cmd.toString());
            return false;
        } else {
            Log.i(DEMOTAG, "NET_DVR_SendRemoteConfig succ, dwCmdType:" + cmd.toString());
        }
        return true;
    }

    public void stopVoiceTalk() {
        if (mVoiceTalkHandle >= 0) {
            if (HCNetSDKJNAInstance.getInstance().NET_DVR_StopVoiceCom(mVoiceTalkHandle)) {
                Log.i(DEMOTAG, "NET_DVR_StopVoiceCom SUCC");
                mVoiceTalkHandle = -1;
            } else {
                Log.i(DEMOTAG, "NET_DVR_StopVoiceCom Failed");
            }
        }
    }

    public void stopVideoCallSession() {
        if (mVideoCall >= 0) {
            HCNetSDKJNAInstance.getInstance().NET_DVR_StopRemoteConfig(mVideoCall);
            Log.i(DEMOTAG, "停止对讲连接");
            mVideoCall = -1;
        }
    }

    private static final HCNetSDKByJNA.fRemoteConfigCallback fVideoCallCallback = new fVideoCallCallback();

    public boolean startVideoCallSession() {
        if (mVideoCall < 0 && mUserID >= 0) {
            HCNetSDKByJNA.NET_DVR_VIDEO_CALL_COND struVideoCall = new HCNetSDKByJNA.NET_DVR_VIDEO_CALL_COND();
            struVideoCall.dwSize = struVideoCall.size();
            struVideoCall.write();

            mVideoCall = HCNetSDKJNAInstance.getInstance().NET_DVR_StartRemoteConfig(mUserID, HCNetSDKByJNA.NET_DVR_VIDEO_CALL_SIGNAL_PROCESS, struVideoCall.getPointer(), struVideoCall.size(), fVideoCallCallback, null);
            Log.e("DEMOTAG", "NET_DVR_StartRemoteConfig mVideoCall  " + mVideoCall + "  " + HCNetSDK.getInstance().NET_DVR_GetLastError());
            if (mVideoCall >= 0) {
                Log.i(DEMOTAG, "NET_DVR_StartRemoteConfig NET_DVR_VIDEO_CALL_SIGNAL_PROCESS succ");
                return true;
            } else {
                Log.i(DEMOTAG, "NET_DVR_StartRemoteConfig NET_DVR_VIDEO_CALL_SIGNAL_PROCESS failed:" + HCNetSDKJNAInstance.getInstance().NET_DVR_GetLastError());
                return false;
            }
        }
        return true;
    }

    //报警回调函数
    public static class FMSGCallBack implements HCNetSDKByJNA.FMSGCallBack {
        @Override
        public void invoke(int lCommand, NET_DVR_ALARMER pAlarmer, Pointer pAlarmInfo, int dwBufLen, Pointer pUser) {
            Log.i(DEMOTAG, "alarm type:" + lCommand);
            //可视对讲报警类型
            if (lCommand == HCNetSDKByJNA.COMM_ALARM_VIDEO_INTERCOM) {
                HCNetSDKByJNA.NET_DVR_VIDEO_INTERCOM_ALARM struIntercomAlarm = new HCNetSDKByJNA.NET_DVR_VIDEO_INTERCOM_ALARM(pAlarmInfo);
                //jna通用的，在获取参数后，需要调用read函数才能使用结构体中字段的值
                struIntercomAlarm.read();

                StringBuilder builder = new StringBuilder();
                builder.append(struIntercomAlarm.struTime.wYear).append("-").append(struIntercomAlarm.struTime.byMonth).append("-").append(struIntercomAlarm.struTime.byDay).append(" ");
                builder.append(struIntercomAlarm.struTime.byHour).append(":").append(struIntercomAlarm.struTime.byMinute).append(":").append(struIntercomAlarm.struTime.bySecond).append("\n");

                builder.append("设备编号：").append(CommonMethod.toValidString(new String(struIntercomAlarm.byDevNumber))).append("\n");
                //报警类型为1时，防区报警信息
                if (struIntercomAlarm.byAlarmType == 1) {
                    builder.append("防区类型：").append(struIntercomAlarm.uAlarmInfo.struZoneAlarm.byZoneType);
                }

                AlarmContent.AlarmItem oneItem = new AlarmContent.AlarmItem(processAlarmType(struIntercomAlarm.byAlarmType), builder.toString(), "ALARM");
                Log.i(DEMOTAG, "add alarm");
                if (mHandler != null) {
                    Message msg = new Message();
                    msg.obj = oneItem;
                    msg.what = ADD_TO_LIST;
                    mHandler.sendMessage(msg);
                }

                //byAlarmType==7的时候，就代表sos报警了。
//                Log.i(DEMOTAG,"NET_DVR_VIDEO_INTERCOM_ALARM byAlarmType:" + struIntercomAlarm.byAlarmType + "byZoneType:" + struIntercomAlarm.uAlarmInfo.struZoneAlarm.byZoneType +
//                        struIntercomAlarm.uAlarmInfo.struZoneAlarm.dwZonendex + CommonMethod.toValidString(new String(struIntercomAlarm.uAlarmInfo.struZoneAlarm.byZoneName)));

            } else if (lCommand == HCNetSDKByJNA.COMM_UPLOAD_VIDEO_INTERCOM_EVENT) {
                HCNetSDKByJNA.NET_DVR_VIDEO_INTERCOM_EVENT struIntercomEvent = new HCNetSDKByJNA.NET_DVR_VIDEO_INTERCOM_EVENT(pAlarmInfo);
                struIntercomEvent.read();

                StringBuilder builder = new StringBuilder();
                String str = "Unknow";
                builder.append(struIntercomEvent.struTime.wYear).append("-").append(struIntercomEvent.struTime.byMonth).append("-").append(struIntercomEvent.struTime.byDay).append(" ");
                builder.append(struIntercomEvent.struTime.byHour).append(":").append(struIntercomEvent.struTime.byMinute).append(":").append(struIntercomEvent.struTime.bySecond).append("\n");

                builder.append("设备编号：").append(CommonMethod.toValidString(new String(struIntercomEvent.byDevNumber))).append("\n");
                //开锁记录
                if (struIntercomEvent.byEventType == 1) {
                    str = "开锁记录";
                    builder.append("开锁方式：").append(struIntercomEvent.uEventInfo.struUnlockRecord.byUnlockType).append("\n");
                    builder.append("操作发起源信息：").append(CommonMethod.toValidString(new String(struIntercomEvent.uEventInfo.struUnlockRecord.byControlSrc)));
                    if (struIntercomEvent.uEventInfo.struUnlockRecord.dwPicDataLen != 0) {
                        try {
                            SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd-hh:mm:ss");
                            String date = sDateFormat.format(new java.util.Date());
                            FileOutputStream file = new FileOutputStream("/mnt/sdcard/" + date + ".bmp");
                            file.write(struIntercomEvent.uEventInfo.struUnlockRecord.pImage.getByteArray(0, struIntercomEvent.uEventInfo.struUnlockRecord.dwPicDataLen), 0, struIntercomEvent.uEventInfo.struUnlockRecord.dwPicDataLen);
                            file.close();
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }//公告信息阅读回执
                else if (struIntercomEvent.byEventType == 2) {
                    str = "公告信息阅读回执";
                    builder.append("公告编号：").append(CommonMethod.toValidString(new String(struIntercomEvent.uEventInfo.struNoticedataReceipt.byNoticeNumber)));
                }

                AlarmContent.AlarmItem oneItem = new AlarmContent.AlarmItem(str, builder.toString(), "EVENT");
                Log.i(DEMOTAG, "add event");
                if (mHandler != null) {
                    Message msg = new Message();
                    msg.obj = oneItem;
                    msg.what = ADD_TO_LIST;
                    mHandler.sendMessage(msg);
                }
            } else {
                Log.i(DEMOTAG, "add xxx");
                AlarmContent.AlarmItem oneitem = new AlarmContent.AlarmItem("lCommand", "test1", "test2");
                if (mHandler != null) {
                    Message msg = new Message();
                    msg.obj = oneitem;
                    msg.what = ADD_TO_LIST;
                    mHandler.sendMessage(msg);
                }
            }
        }
    }

    private static String processAlarmType(int alarmType) {
        StringBuilder builder = new StringBuilder();
        switch (alarmType) {
            case 1:
                builder.append("防区报警");
                break;
            case 2:
                builder.append("防拆报警");
                break;
            case 3:
                builder.append("劫持报警");
                break;
            case 4:
                builder.append("多次密码开锁失败报警");
                break;
            case 5:
                builder.append("门没开");
                break;
            case 6:
                builder.append("门没关");
                break;
            case 7:
                builder.append("SOS");
                break;
            case 8:
                builder.append("通话对讲");
            default:
                builder.append(alarmType);
                break;
        }
        return builder.toString();
    }

    // 报警回调函数声明
    private static final HCNetSDKByJNA.FMSGCallBack fMSFCallBack = new FMSGCallBack();

    public void startAlarm(int iUserID) {
        if (mAlarmID < 0) {
            Pointer pUser = null;
            //设置报警回调函数
            if (!HCNetSDKJNAInstance.getInstance().NET_DVR_SetDVRMessageCallBack_V30(fMSFCallBack, pUser)) {
                Log.i(DEMOTAG, "NET_DVR_SetDVRMessageCallBack_V30 failed:" + HCNetSDKJNAInstance.getInstance().NET_DVR_GetLastError());
            }

            //启动报警布防，用户需要维护这个布防m_lAlarmID句柄，在关闭布防时使用。
            mAlarmID = HCNetSDKJNAInstance.getInstance().NET_DVR_SetupAlarmChan_V30(iUserID);
        }
    }

    public void stopAlarm() {
        if (mAlarmID >= 0) {
            //关闭布防
            HCNetSDKJNAInstance.getInstance().NET_DVR_CloseAlarmChan_V30(mAlarmID);
            mAlarmID = -1;
        }
    }

    public void startAlarm_V41(int iUserID) {
        if (mAlarmID < 0) {
            Pointer pUser = null;
            if (!HCNetSDKJNAInstance.getInstance().NET_DVR_SetDVRMessageCallBack_V30(fMSFCallBack, pUser)) {
                Log.i(DEMOTAG, "NET_DVR_SetDVRMessageCallBack_V30 failed:" + HCNetSDKJNAInstance.getInstance().NET_DVR_GetLastError());
            }

            HCNetSDKByJNA.NET_DVR_SETUPALARM_PARAM arlarmParam = new HCNetSDKByJNA.NET_DVR_SETUPALARM_PARAM();
            arlarmParam.dwSize = arlarmParam.size();
            arlarmParam.byRetDevInfoVersion = 1;
            arlarmParam.write();
            mAlarmID = HCNetSDKJNAInstance.getInstance().NET_DVR_SetupAlarmChan_V41(iUserID, arlarmParam.getPointer());
        } else {
            HCNetSDKJNAInstance.getInstance().NET_DVR_CloseAlarmChan_V30(mAlarmID);
            mAlarmID = -1;
        }
    }

    public boolean SetNoticeData(DataModal.NoticeData nt) {
        HCNetSDKByJNA.NET_DVR_NOTICE_DATA struNoticeData = new HCNetSDKByJNA.NET_DVR_NOTICE_DATA();
        struNoticeData.dwSize = struNoticeData.size();
        struNoticeData.struTime.wYear = (short) nt.year;
        struNoticeData.struTime.byMonth = (byte) nt.month;
        struNoticeData.struTime.byDay = (byte) nt.day;
        struNoticeData.struTime.byHour = (byte) nt.hour;
        struNoticeData.struTime.byMinute = (byte) nt.minute;
        struNoticeData.struTime.bySecond = (byte) nt.second;
        struNoticeData.byLevel = (byte) nt.noticeLevel;
        struNoticeData.byPicNum = (byte) nt.picNum;
        System.arraycopy(nt.noticeDetail.getBytes(), 0, struNoticeData.byNoticeDetail, 0, nt.noticeDetail.length());
        System.arraycopy(nt.noticeNumber.getBytes(), 0, struNoticeData.byNoticeNumber, 0, nt.noticeNumber.length());
        System.arraycopy(nt.noticeTheme.getBytes(), 0, struNoticeData.byNoticeTheme, 0, nt.noticeTheme.length());

        for (int i = 0; i < HCNetSDKByJNA.MAX_NOTICE_PIC_NUM && nt.len[i] > 0; i++) {
            HCNetSDKByJNA.BYTE_ARRAY ptrByte = new HCNetSDKByJNA.BYTE_ARRAY(nt.len[i]);
            System.arraycopy(nt.stream[i], 0, ptrByte.byValue, 0, nt.len[i]);
            ptrByte.write();
            struNoticeData.struNoticePic[i].pPicData = ptrByte.getPointer();
            struNoticeData.struNoticePic[i].dwPicDataLen = nt.len[i];
            struNoticeData.struNoticePic[i].write();
        }
        struNoticeData.write();

        boolean iRet = HCNetSDKJNAInstance.getInstance().NET_DVR_RemoteControl(mUserID, HCNetSDKByJNA.NET_DVR_REMOTECONTROL_NOTICE_DATA, struNoticeData.getPointer(), struNoticeData.size());
        if (!iRet) {
            Log.i(DEMOTAG, "NET_DVR_REMOTECONTROL_NOTICE_DATA failed:" + HCNetSDKJNAInstance.getInstance().NET_DVR_GetLastError());
        }
        return iRet;
    }


    public String CallEvaluator() {
        if (mUserID >= 0) {
            return CallEvaluator(mUserID);
        }
        return null;
    }

    /**
     * SOS报警触发
     *
     * @param iUserID
     */
    private String SOSAlarmTrigger(int iUserID) {
        String str = new String("PUT /ISAPI/VideoIntercom/SOSAlarmTrigger");
        String strInBuffer = new String("<SOSAlarmTrigger version=\"2.0\" xmlns=\"http://www.isapi.org/ver20/XMLSchema\">\n" + "</SOSAlarmTrigger>\n");

        return POST_STD_XML(iUserID, str, strInBuffer);
    }

    public String SOSAlarmTrigger() {
        if (mUserID >= 0) {
            return SOSAlarmTrigger(mUserID);
        }
        return null;
    }

    /**
     * 呼叫电梯
     *
     * @param iUserID
     */
    private String CallEvaluator(int iUserID) {
        String str = new String("POST /ISAPI/VideoIntercom/callElevator");
        String strInBuffer = new String("<CallElevatorCfg version=\"2.0\" xmlns=\"http://www.isapi.org/ver20/XMLSchema\">\n" + "</CallElevatorCfg>\n");

        return POST_STD_XML(iUserID, str, strInBuffer);
    }


    private String POST_STD_XML(int iUserID, String str, String strInBuffer) {
        HCNetSDKByJNA.NET_DVR_XML_CONFIG_INPUT struInput = new HCNetSDKByJNA.NET_DVR_XML_CONFIG_INPUT();
        struInput.dwSize = struInput.size();

        HCNetSDKByJNA.BYTE_ARRAY ptrUrl = new HCNetSDKByJNA.BYTE_ARRAY(HCNetSDKByJNA.BYTE_ARRAY_LEN);
        System.arraycopy(str.getBytes(), 0, ptrUrl.byValue, 0, str.length());
        ptrUrl.write();
        struInput.lpRequestUrl = ptrUrl.getPointer();
        struInput.dwRequestUrlLen = str.length();

        HCNetSDKByJNA.BYTE_ARRAY ptrByte = new HCNetSDKByJNA.BYTE_ARRAY(10 * HCNetSDKByJNA.BYTE_ARRAY_LEN);
        ptrByte.byValue = strInBuffer.getBytes();
        ptrByte.write();
        struInput.lpInBuffer = ptrByte.getPointer();
        struInput.dwInBufferSize = strInBuffer.length();
        struInput.write();

        HCNetSDKByJNA.NET_DVR_XML_CONFIG_OUTPUT struOutput = new HCNetSDKByJNA.NET_DVR_XML_CONFIG_OUTPUT();
        struOutput.dwSize = struOutput.size();

        HCNetSDKByJNA.BYTE_ARRAY ptrOutByte = new HCNetSDKByJNA.BYTE_ARRAY(HCNetSDKByJNA.ISAPI_DATA_LEN);
        struOutput.lpOutBuffer = ptrOutByte.getPointer();
        struOutput.dwOutBufferSize = HCNetSDKByJNA.ISAPI_DATA_LEN;
        ;

        HCNetSDKByJNA.BYTE_ARRAY ptrStatusByte = new HCNetSDKByJNA.BYTE_ARRAY(HCNetSDKByJNA.ISAPI_STATUS_LEN);
        struOutput.lpStatusBuffer = ptrStatusByte.getPointer();
        struOutput.dwStatusSize = HCNetSDKByJNA.ISAPI_STATUS_LEN;
        struOutput.write();

        if (!HCNetSDKJNAInstance.getInstance().NET_DVR_STDXMLConfig(iUserID, struInput, struOutput)) {
            struOutput.read();
            Log.i(DEMOTAG, "lpRequestUrl:" + str);
            Log.i(DEMOTAG, "NET_DVR_STDXMLConfig failed with:" + HCNetSDKJNAInstance.getInstance().NET_DVR_GetLastError());
            String str2 = CommonMethod.toValidString(new String(struOutput.lpStatusBuffer.getByteArray(0, struOutput.dwReturnedXMLSize)));
            if (str2.isEmpty()) {
                return null;
            } else {
                return str2;
            }
        } else {
            struOutput.read();
            Log.i(DEMOTAG, "lpRequestUrl:" + str);
            Log.i(DEMOTAG, "NET_DVR_STDXMLConfig Succ!!!!!!!!!!!!!!!");
            String str2 = CommonMethod.toValidString(new String(struOutput.lpOutBuffer.getByteArray(0, struOutput.dwReturnedXMLSize)));
            if (str2.isEmpty()) {
                return null;
            } else {
                return str2;
            }
        }
    }

    private void DELETE_STD_XML(int iUserID, String str) {
        HCNetSDKByJNA.NET_DVR_XML_CONFIG_INPUT struInput = new HCNetSDKByJNA.NET_DVR_XML_CONFIG_INPUT();
        struInput.dwSize = struInput.size();

        HCNetSDKByJNA.BYTE_ARRAY ptrDeleteFaceLibUrl = new HCNetSDKByJNA.BYTE_ARRAY(HCNetSDKByJNA.BYTE_ARRAY_LEN);
        System.arraycopy(str.getBytes(), 0, ptrDeleteFaceLibUrl.byValue, 0, str.length());
        ptrDeleteFaceLibUrl.write();
        struInput.lpRequestUrl = ptrDeleteFaceLibUrl.getPointer();
        struInput.dwRequestUrlLen = str.length();
        struInput.lpInBuffer = null;
        struInput.dwInBufferSize = 0;
        struInput.write();

        HCNetSDKByJNA.NET_DVR_XML_CONFIG_OUTPUT struOutput = new HCNetSDKByJNA.NET_DVR_XML_CONFIG_OUTPUT();
        struOutput.dwSize = struOutput.size();
        struOutput.lpOutBuffer = null;
        struOutput.dwOutBufferSize = 0;

        HCNetSDKByJNA.BYTE_ARRAY ptrStatusByte = new HCNetSDKByJNA.BYTE_ARRAY(HCNetSDKByJNA.ISAPI_STATUS_LEN);
        struOutput.lpStatusBuffer = ptrStatusByte.getPointer();
        struOutput.dwStatusSize = HCNetSDKByJNA.ISAPI_STATUS_LEN;
        struOutput.write();

        if (!HCNetSDKJNAInstance.getInstance().NET_DVR_STDXMLConfig(iUserID, struInput, struOutput)) {
            Log.i(DEMOTAG, "lpRequestUrl:" + str);
            Log.i(DEMOTAG, "NET_DVR_STDXMLConfig DELETE failed with:" + " " + HCNetSDKJNAInstance.getInstance().NET_DVR_GetLastError());
        } else {
            System.out.println("lpRequestUrl:" + str);
            System.out.println("NET_DVR_STDXMLConfig DELETE Succ!");
        }
    }

}